package com.uinnova.product.eam.service.cj.service.impl;

import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSON;
import com.binary.core.lang.StringUtils;
import com.binary.core.util.BinaryUtils;
import com.binary.jdbc.Page;
import com.uinnova.product.eam.comm.model.es.ArchReview;
import com.uinnova.product.eam.comm.model.es.PlanProcessRelationInfo;
import com.uinnova.product.eam.model.asset.AnnotationMsgDTO;
import com.uinnova.product.eam.model.cj.domain.*;
import com.uinnova.product.eam.model.cj.enums.QuestionStatusEnum;
import com.uinnova.product.eam.model.cj.request.PlanModuleAnnotationRequest;
import com.uinnova.product.eam.model.cj.request.PlanModuleAnswerRequest;
import com.uinnova.product.eam.model.cj.vo.PlanChapterAnnotationVO;
import com.uinnova.product.eam.model.cj.vo.PlanModuleAnnotationVO;
import com.uinnova.product.eam.model.cj.vo.QuestionAnswerVO;
import com.uinnova.product.eam.model.constants.Constants;
import com.uinnova.product.eam.model.vo.PlanModuleAnnotationReq;
import com.uinnova.product.eam.service.IEamNoticeService;
import com.uinnova.product.eam.service.cj.dao.*;
import com.uinnova.product.eam.service.cj.service.*;
import com.uinnova.product.eam.service.exception.BusinessException;
import com.uinnova.product.eam.service.todo.GTJobSvc;
import com.uinnova.product.eam.service.todo.dto.GTFinishPendingJobInfo;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.permission.base.SysUser;
import com.uino.bean.permission.business.UserInfo;
import com.uino.bean.permission.query.CSysUser;
import com.uino.dao.util.ESUtil;
import com.uino.util.sys.SysUtil;
import lombok.extern.log4j.Log4j2;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 方案批注service实现
 *
 * @author zhaoxin
 * @since 2022-3-1 20:40:43
 */
@Service
@Log4j2
public class PlanModuleAnnotationServiceImpl implements PlanModuleAnnotationService {

    private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Resource
    private ChapterContextDao chapterContextDao;

    @Resource
    private PlanModuleAnnotationDao planModuleAnnotationDao;

    @Resource
    private PlanChapterQuestionDao planChapterQuestionDao;

    @Resource
    private PlanChapterInstanceDao planChapterInstanceDao;

    @Resource
    private FlowableService flowableService;

    @Resource
    private IUserApiSvc userApiSvc;

    @Autowired
    private IEamNoticeService noticeService;

    @Autowired
    private ArchReviewDao archReviewDao;

    @Autowired
    private PlanDesignInstanceService planDesignInstanceService;
    @Autowired
    private PlanChapterInstanceService planChapterInstanceService;
    @Autowired
    private PlanTemplateChapterService planTemplateChapterService;
    @Autowired
    private GTJobSvc gtJobSvc;
    @Value("${gt.data.imitate:false}")
    private Boolean gtDataImitate;
    @Resource
    private PlanProcessRelationInfoDao planProcessRelationInfoDao;

    /**
     * 批注查询
     *
     * @param planId    方案id
     * @param chapterId 章节id
     * @param delFlag   查询状态
     * @return {@link PlanModuleAnnotationEntity}
     */
    @Override
    public List<PlanModuleAnnotationEntity> list(Long planId, Long chapterId, Boolean delFlag) {
        if (planId == null && chapterId == null && delFlag == null) {
            return Collections.emptyList();
        }

        BoolQueryBuilder query = QueryBuilders.boolQuery();

        if (planId != null) {
            query.must(QueryBuilders.termQuery("planId", planId));
        }

        if (chapterId != null) {
            query.must(QueryBuilders.termQuery("planChapterId", chapterId));
        }

        if (delFlag != null) {
            query.must(QueryBuilders.termQuery("delFlag", delFlag));
        }

        return planModuleAnnotationDao.getListByQuery(query);
    }

    @Override
    public void deleteAnnotationByPlanId(Long planId) {
        if (planId == null) {
            throw new BusinessException("方案主键不能为空!");
        }
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.termQuery("planId", planId));
        planModuleAnnotationDao.deleteByQuery(query, true);
    }

    /**
     * 方案批注新增
     *
     * @param request {@link PlanModuleAnnotationRequest}
     * @return 批注id
     */
    @Override
    public Long saveAnnotation(PlanModuleAnnotationRequest request) {
        ChapterContext context = chapterContextDao.getById(request.getChapterId());

        ContextModule module = context.getModuleList().stream()
                .filter(m -> request.getPlanChapterModuleId().equals(m.getId()))
                .findFirst().orElseThrow(() -> new BusinessException(Constants.PLAN_MODULE_NOT_FOUND));

        PlanModuleAnnotationEntity annotationEntity = PlanModuleAnnotationEntity.builder()
                .planId(context.getPlanId())
                .planChapterId(context.getId())
                .planChapterModuleId(module.getId())
                .annotationContent(request.getAnnotationContent())
                .delFlag(false)
                .taskDefinitionKey(request.getTaskDefinitionKey())
                .build();

        // 是否为问题
        boolean problem = request.getProblem() != null ? request.getProblem() : false;
        annotationEntity.setProblem(problem);

        SysUser user = SysUtil.getCurrentUserInfo();
        annotationEntity.setId(ESUtil.getUUID());
        annotationEntity.setCreatorCode(user.getLoginCode());
        annotationEntity.setCreatorName(user.getUserName());
        annotationEntity.setCreateTime(ESUtil.getNumberDateTime());

        planModuleAnnotationDao.saveOrUpdate(annotationEntity);

        return annotationEntity.getId();
    }

    @Override
    public Long saveAnnotationWithNotice(PlanModuleAnnotationReq annotationVo) {
        ChapterContext context = chapterContextDao.getById(annotationVo.getChapterId());

        ContextModule module = context.getModuleList().stream()
                .filter(m -> annotationVo.getPlanChapterModuleId().equals(m.getId()))
                .findFirst().orElseThrow(() -> new BusinessException(Constants.PLAN_MODULE_NOT_FOUND));

        PlanModuleAnnotationEntity annotationEntity = PlanModuleAnnotationEntity.builder()
                .planId(context.getPlanId())
                .planChapterId(context.getId())
                .planChapterModuleId(module.getId())
                .annotationContent(annotationVo.getAnnotationContent())
                .delFlag(false)
                .taskDefinitionKey(annotationVo.getTaskDefinitionKey())
                .build();
        annotationEntity.setProblem(false);
        SysUser user = SysUtil.getCurrentUserInfo();
        annotationEntity.setId(ESUtil.getUUID());
        annotationEntity.setCreatorCode(user.getLoginCode());
        annotationEntity.setCreatorName(user.getUserName());
        annotationEntity.setCreateTime(ESUtil.getNumberDateTime());
        planModuleAnnotationDao.saveOrUpdate(annotationEntity);

        this.pushQuestionCorrectionNotice("create", annotationEntity, annotationVo.getArchReviewName()
                , annotationVo.getArchReviewId(), annotationVo.getProcessInstanceId(), annotationVo.getProcessSubmitter());
        return annotationEntity.getId();
    }

    /**
     * 方案批注删除
     *
     * @param request {@link PlanModuleAnnotationRequest}
     */
    @Override
    public void deleteAnnotation(PlanModuleAnnotationRequest request) {
        PlanModuleAnnotationEntity target = planModuleAnnotationDao.getById(request.getAnnotationId());
        target.setDelFlag(true);
        planModuleAnnotationDao.saveOrUpdate(target);
    }

    /**
     * 方案批注修改
     *
     * @param request {@link PlanModuleAnnotationRequest}
     */
    @Override
    public void modifyAnnotation(PlanModuleAnnotationRequest request) {
        PlanModuleAnnotationEntity target = planModuleAnnotationDao.getById(request.getAnnotationId());
        SysUser user = SysUtil.getCurrentUserInfo();
        if (!StringUtils.isEmpty(request.getAnnotationContent())) {
            target.setAnnotationContent(request.getAnnotationContent());
        }
        if (request.getProblem() != null) {
            target.setProblem(request.getProblem());
        }
        if (!StringUtils.isEmpty(request.getTaskDefinitionKey())) {
            target.setTaskDefinitionKey(request.getTaskDefinitionKey());
        }
        target.setModifyTime(ESUtil.getNumberDateTime());
        target.setModifierCode(user.getLoginCode());
        target.setModifierName(user.getLoginCode());
        planModuleAnnotationDao.saveOrUpdate(target);
    }

    /**
     * 方案批注分页查询
     *
     * @param request {@link PlanModuleAnnotationRequest}
     * @return map说明 ： size - 批注的个数, annotationList - 批注列表
     */
    @Override
    public Map<String, Object> list(PlanModuleAnnotationRequest request) {
        BoolQueryBuilder query = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("delFlag", false))
                .must(QueryBuilders.termQuery("planId", request.getPlanId()));
        String processInstanceId = null;
        if (!StringUtils.isBlank(request.getTaskDefinitionKey())) {
            processInstanceId = request.getTaskDefinitionKey();
        } else {
            ArchReview archReview = queryArchReviewBizKey(request.getPlanId());
            if (!BinaryUtils.isEmpty(archReview)) {
                // 架构设计方案 审批结束 无当前流程的方案 取最后一次流程中的批注
                processInstanceId = archReview.getProcessInstanceId();
            } else {
                // 设计资产方案 根据发布方案与流程对应的版本关系 取当时的批注
                PlanProcessRelationInfo planProcessRelationInfo = getByPlanId(request.getPlanId());
                if (!BinaryUtils.isEmpty(planProcessRelationInfo)) {
                    processInstanceId = planProcessRelationInfo.getProcessInstanceId();
                }
            }
        }

        if (!BinaryUtils.isEmpty(processInstanceId)) {
            query.must(QueryBuilders.termQuery("taskDefinitionKey.keyword", processInstanceId));
        }

        FieldSortBuilder sortBuilder = new FieldSortBuilder("createTime").order(SortOrder.DESC);
        List<PlanModuleAnnotationEntity> persistentList = planModuleAnnotationDao.getSortListByQuery(1, 3000, query,
                ListUtil.of(sortBuilder)).getData();

        int annotationSize;
        List<PlanModuleAnnotationVO> annotationList;
        if (BinaryUtils.isEmpty(persistentList)) {
            annotationSize = 0;
            annotationList = Collections.emptyList();
        } else {

            BoolQueryBuilder queryByPlanId = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("planId",
                    request.getPlanId())).must(QueryBuilders.termQuery("deleted", false));

            List<ChapterInstance> chapterList = planChapterInstanceDao.getListByQuery(queryByPlanId);
            queryByPlanId = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("planId",
                    request.getPlanId()));
            List<ChapterContext> contextList = chapterContextDao.getListByQuery(queryByPlanId);

            Map<Long, ChapterInstance> chapterMap = chapterList.stream().collect(Collectors.toMap(ChapterInstance::getId
                    , Function.identity()));

            Map<Long, ChapterContext> contextMap =
                    contextList.stream().collect(Collectors.toMap(ChapterContext::getId, Function.identity()));

            String finalProcessInstanceId = processInstanceId;
            annotationList =
                    persistentList.stream().map(p -> buildAnnotationVoList(chapterMap, contextMap, p, finalProcessInstanceId))
                            .filter(Objects::nonNull)
                            .collect(Collectors.toList());
            annotationSize = annotationList.size();

        }

        Map<String, Object> targetMap = new HashMap<>((int) (2 / 0.75) + 1);
        targetMap.put("annotationSize", annotationSize);
        targetMap.put("annotationList", annotationList);

        return targetMap;
    }

    /**
     * 根据方案id查询提交的审批信息
     * @param planId
     * @return
     */
    private ArchReview queryArchReviewBizKey(Long planId) {
        TermQueryBuilder query = QueryBuilders.termQuery("planIds", planId);
        Page<ArchReview> page = archReviewDao.getSortListByQuery(1,1, query,"createTime", false);
        return CollectionUtils.isEmpty(page.getData()) ? null : page.getData().get(0);
    }
    /**
     * 根据方案id查询对应版本流程关联关系
     * @param planId
     * @return
     */
    private PlanProcessRelationInfo getByPlanId(Long planId) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("planId", planId));
        List<PlanProcessRelationInfo> list = planProcessRelationInfoDao.selectListByQuery(1, 1, queryBuilder);
        if (BinaryUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }


    private PlanModuleAnnotationVO buildAnnotationVoList(Map<Long, ChapterInstance> chapterMap,
                                                         Map<Long, ChapterContext> contextMap,
                                                         PlanModuleAnnotationEntity annotationPersistent,
                                                         String taskDefinitionKey) {

        Long targetModuleId = annotationPersistent.getPlanChapterModuleId();
        Long targetChapterId = annotationPersistent.getPlanChapterId();

        ChapterInstance targetChapter = chapterMap.get(targetChapterId);
        ChapterContext targetContext = contextMap.get(targetChapterId);
        if (BinaryUtils.isEmpty(targetChapter) || BinaryUtils.isEmpty(targetContext)) {
            return null;
        }
        ContextModule targetModule =
                targetContext.getModuleList().stream().filter(module -> targetModuleId.equals(module.getId()))
                        .findFirst()
                        .orElse(null);

        if (BinaryUtils.isEmpty(targetModule)) {
            return null;
        }
        PlanTemplateChapterData moduleDefinition = targetModule.getModuleDefinition();
        Integer moduleType = moduleDefinition.getType();
        String moduleName = "";

        // 制品
        int product = 1;
        // 表格
        int table = 2;
        // 富文本
        int richText = 3;
        //清单制品
        int dataSet = 4;
        //附件
        int appendix = 5;
        if (moduleType == product) {
            moduleName = moduleDefinition.getProductName();
        } else if (moduleType == table) {
            moduleName = moduleDefinition.getDataTableName();
        } else if (moduleType == richText) {
            moduleName = moduleDefinition.getRichTextName();
        } else if (moduleType == dataSet) {
            moduleName = moduleDefinition.getDataSetName();
        } else if (moduleType == appendix) {
            moduleName = moduleDefinition.getAppendixName();
        }

        String author = annotationPersistent.getCreatorCode();
        if (!BinaryUtils.isEmpty(annotationPersistent.getCreatorName())) {
            author = annotationPersistent.getCreatorName();
        } else {
            String creatorCode = annotationPersistent.getCreatorCode();
            CSysUser cdt = new CSysUser();
            cdt.setLoginCodeEqual(creatorCode);
            List<SysUser> shareUsers = userApiSvc.getSysUserByCdt(cdt);
            if (!CollectionUtils.isEmpty(shareUsers)) {
                SysUser sysUser = shareUsers.get(0);
                if (sysUser != null) {
                    author = sysUser.getUserName();
                }
            }
        }

        PlanModuleAnnotationVO vo = new PlanModuleAnnotationVO();
        vo.setPlanChapterModuleId(targetModule.getId());
        vo.setPlanChapterModuleName(moduleName);
        vo.setPlanChapterName(targetChapter.getName());
        vo.setAnnotationContent(annotationPersistent.getAnnotationContent());
        vo.setProblem(annotationPersistent.getProblem());
        vo.setAnnotationId(annotationPersistent.getId());
        vo.setCreateTime(annotationPersistent.getCreateTime());
        vo.setAnnotationTitle(String.format("%s/%s", vo.getPlanChapterName(), vo.getPlanChapterModuleName()));
        vo.setAuthor(author);

        // 获取试题的属性
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.termQuery("annotationId", annotationPersistent.getId()));
        List<PlanChapterQuestion> questionList = planChapterQuestionDao.getListByQuery(queryBuilder);
        if (!CollectionUtils.isEmpty(questionList)) {
            PlanChapterQuestion question = questionList.get(0);
            vo.setQuestionDate(question.getCreateTime());
            vo.setQuestionState(QuestionStatusEnum.getQuestionDesc(question.getQuestionState()));
        }
        boolean questionPower = Objects.equals(annotationPersistent.getCreatorCode(), SysUtil.getCurrentUserInfo().getLoginCode());
        if (questionPower && !StringUtils.isEmpty(taskDefinitionKey) && !StringUtils.isEmpty(annotationPersistent.getTaskDefinitionKey())
                && Objects.equals(taskDefinitionKey, annotationPersistent.getTaskDefinitionKey())) {
            vo.setQuestionPower(true);
        }

        //动态--仅批注有
        if (Boolean.FALSE.equals(annotationPersistent.getProblem())) {
            List<QuestionAnswerVO> answerList = annotationPersistent.getAnswerList();
            List<PlanChapterAnnotationVO.Answer> answers = new ArrayList<>();
            if (CollectionUtils.isEmpty(answerList)) {
                answerList = new ArrayList<>();
            }
            for (int i = answerList.size() - 1; i >= 0; i--) {
                PlanChapterAnnotationVO.Answer answer = new PlanChapterAnnotationVO.Answer();
                answer.setCreator(answerList.get(i).getUsername());
                answer.setAction("回复");
                answer.setAnswer(answerList.get(i).getAnswer());
                answer.setCreateTime(transDateFormat(answerList.get(i).getAnswerTime()));
                answers.add(answer);
            }
            PlanChapterAnnotationVO.Answer createAnswer = new PlanChapterAnnotationVO.Answer();
            createAnswer.setCreator(getUserNameByLoginCode(annotationPersistent.getCreatorCode()));
            createAnswer.setAction("创建");
            createAnswer.setCreateTime(transDateFormat(annotationPersistent.getCreateTime()));
            answers.add(createAnswer);
            vo.setAnswers(answers);
        }
        return vo;
    }

    @Override
    public Page<PlanModuleAnnotationEntity> getSortListByQuery(int pageNum, int pageSize, QueryBuilder query, List<SortBuilder<?>> sorts) {
        return planModuleAnnotationDao.getSortListByQuery(pageNum, pageSize, query, sorts);
    }

    @Override
    public PlanModuleAnnotationEntity getById(Long id) {
        return planModuleAnnotationDao.getById(id);
    }

    @Override
    public Long saveAnswer(PlanModuleAnswerRequest request) {
        PlanModuleAnnotationEntity annotation = planModuleAnnotationDao.getById(request.getId());
        QuestionAnswerVO answer = new QuestionAnswerVO();
        answer.setAnswer(request.getAnswer());
        answer.setAnswerTime(ESUtil.getNumberDateTime());
        UserInfo userInfo = userApiSvc.getUserInfoById(SysUtil.getCurrentUserInfo().getId());
        answer.setUsername(userInfo.getUserName());

        List<QuestionAnswerVO> answerList = annotation.getAnswerList();
        if (CollectionUtils.isEmpty(answerList)) {
            answerList = new ArrayList<>();
        }
        answerList.add(answer);
        annotation.setAnswerList(answerList);
        //推送消息
        String msgType = SysUtil.getCurrentUserInfo().getLoginCode().equals(annotation.getCreatorCode()) ? "reply_from_creator" : "reply_from_other";
        this.pushQuestionCorrectionNotice(msgType, annotation, request.getArchReviewName()
                , request.getArchReviewId(), request.getProcessInstanceId(), request.getProcessSubmitter());
        return planModuleAnnotationDao.saveOrUpdate(annotation);
    }

    private void pushQuestionCorrectionNotice(String msgType, PlanModuleAnnotationEntity annotation
            , String archReviewName, Long archReviewId, String processInstanceId, String processSubmitter) {
        if (StringUtils.isBlank(archReviewName)
                || archReviewId == null
                || StringUtils.isBlank(processInstanceId)
                || StringUtils.isBlank(processSubmitter)) {
            return;
        }
        AnnotationMsgDTO annotationMsgDTO = new AnnotationMsgDTO();
        annotationMsgDTO.setType(msgType);
        String operator = "-";
        switch (msgType) {
            case "create":
                operator = annotation.getCreatorCode();
                annotationMsgDTO.setOwner(processSubmitter);
                break;
            case "reply_from_other":
                operator = SysUtil.getCurrentUserInfo().getLoginCode();
                annotationMsgDTO.setOwner(annotation.getCreatorCode());
                break;
            case "reply_from_creator":
                operator = SysUtil.getCurrentUserInfo().getLoginCode();
                annotationMsgDTO.setOwner(processSubmitter);
                break;
            default:
                return;
        }
        annotationMsgDTO.setOperator(getUserNameByLoginCode(operator));
        annotationMsgDTO.setArchReviewId(archReviewId);
        annotationMsgDTO.setArchReviewName(archReviewName);
        annotationMsgDTO.setProcessInstanceId(processInstanceId);
        noticeService.annotationMsgSave(annotationMsgDTO);
    }

    private String getUserNameByLoginCode(String loginCode) {
        CSysUser cdt = new CSysUser();
        cdt.setLoginCodeEqual(loginCode);
        List<SysUser> sysUserList = userApiSvc.getSysUserByCdt(cdt);
        return CollectionUtils.isEmpty(sysUserList) ? loginCode : sysUserList.get(0).getUserName();
    }

    @Override
    public Page<PlanChapterAnnotationVO> findGTAnnotationList(PlanModuleAnswerRequest request) {
        if (request == null) {
            throw new BusinessException("请求参数不能为空!");
        }
        if (StringUtils.isBlank(request.getBusinessKey()) && request.getArchReviewId() == null) {
            throw new BusinessException("缺少参数");
        }
        ArchReview archReview;
        if (!StringUtils.isBlank(request.getBusinessKey())) {
            archReview = archReviewDao.getById(Long.valueOf(request.getBusinessKey()));
        } else {
            archReview = archReviewDao.getById(request.getArchReviewId());
        }
        String processInstanceId = "-";
        if (!StringUtils.isBlank(archReview.getProcessInstanceId())) {
            processInstanceId = archReview.getProcessInstanceId();
        }
        Assert.notNull(archReview, "未找到架构评审提交记录");

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.termsQuery("planId", archReview.getPlanIds()));
        queryBuilder.must(QueryBuilders.termQuery("taskDefinitionKey.keyword", processInstanceId));
        queryBuilder.must(QueryBuilders.termQuery("problem", false));
        queryBuilder.must(QueryBuilders.termQuery("delFlag", false));

        Page<PlanModuleAnnotationEntity> annotationPage = planModuleAnnotationDao.getSortListByQuery(request.getPageNum(), request.getPageSize(), queryBuilder, "createTime", false);
        List<PlanChapterAnnotationVO> annotations = new ArrayList<>();
        if (!CollectionUtils.isEmpty(annotationPage.getData())) {
            Map<Long, PlanDesignInstance> planMap = new HashMap<>();
            List<PlanDesignInstance> plans = planDesignInstanceService.getByIds(archReview.getPlanIds());
            if (!CollectionUtils.isEmpty(plans)) {
                planMap = plans.stream().collect(Collectors.toMap(PlanDesignInstance::getId, Function.identity()));
            }
            CSysUser cdt = new CSysUser();
            cdt.setLoginCodes(annotationPage.getData().stream().map(PlanModuleAnnotationEntity::getCreatorCode).distinct().toArray(String[]::new));
            List<SysUser> sysUsers = userApiSvc.getSysUserByCdt(cdt);
            Map<String, SysUser> userMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(sysUsers)) {
                userMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getLoginCode, Function.identity()));
            }

            for (PlanModuleAnnotationEntity annotationEntity : annotationPage.getData()) {
                PlanChapterAnnotationVO annotation = new PlanChapterAnnotationVO();
                annotation.setId(annotationEntity.getId());
                annotation.setAnnotation(annotationEntity.getAnnotationContent());
                annotation.setCreator(annotationEntity.getCreatorCode());
                annotation.setCreatorName(userMap.containsKey(annotationEntity.getCreatorCode()) ? userMap.get(annotationEntity.getCreatorCode()).getUserName() : "-");
                annotation.setPlanName(planMap.containsKey(annotationEntity.getPlanId()) ? planMap.get(annotationEntity.getPlanId()).getName() : "-");
                annotation.setPlanId(annotationEntity.getPlanId());
                annotation.setPlanChapterId(annotationEntity.getPlanChapterId());
                annotation.setPlanChapterContextId(annotationEntity.getPlanChapterModuleId());

                // 章节信息
                ChapterInstance chapterInstance = planChapterInstanceService.getPlanChapterInstance(annotationEntity.getPlanChapterId());
                String moduleName = chapterInstance.getName();
                ChapterContext context = chapterContextDao.getById(annotationEntity.getPlanChapterId());
                if (!CollectionUtils.isEmpty(context.getModuleList())) {
                    ContextModule module = context.getModuleList().stream()
                            .collect(Collectors.toMap(ContextModule::getId, Function.identity()))
                            .get(annotationEntity.getPlanChapterModuleId());
                    if (module != null) {
                        PlanTemplateChapterData moduleDefinition = module.getModuleDefinition();
                        Integer moduleType = moduleDefinition.getType();
                        // 制品
                        int product = 1;
                        // 表格
                        int table = 2;
                        // 富文本
                        int richText = 3;
                        //清单制品
                        int dataSet = 4;
                        //附件
                        int appendix = 5;
                        if (moduleType == product) {
                            moduleName = moduleName + Constants.SLASH + moduleDefinition.getProductName();
                        } else if (moduleType == table) {
                            moduleName = moduleName + Constants.SLASH + moduleDefinition.getDataTableName();
                        } else if (moduleType == richText) {
                            moduleName = moduleName + Constants.SLASH + moduleDefinition.getRichTextName();
                        } else if (moduleType == dataSet) {
                            moduleName = moduleName + Constants.SLASH + moduleDefinition.getDataSetName();
                        } else if (moduleType == appendix) {
                            moduleName = moduleName + Constants.SLASH + moduleDefinition.getAppendixName();
                        }
                    }
                }
                annotation.setModule(moduleName);
                List<QuestionAnswerVO> answerList = annotationEntity.getAnswerList();
                if (CollectionUtils.isEmpty(answerList)) {
                    answerList = new ArrayList<>();
                }
                //最新回复
                if (!CollectionUtils.isEmpty(answerList)) {
                    annotation.setLatestAnswer(answerList.get(answerList.size() - 1).getAnswer());
                } else {
                    annotation.setLatestAnswer(Constants.CENTRE_LINE);
                }
                //动态
                List<PlanChapterAnnotationVO.Answer> answers = new ArrayList<>();
                for (int i = answerList.size() - 1; i >= 0; i--) {
                    PlanChapterAnnotationVO.Answer answer = new PlanChapterAnnotationVO.Answer();
                    answer.setCreator(answerList.get(i).getUsername());
                    answer.setAction("回复");
                    answer.setAnswer(answerList.get(i).getAnswer());
                    answer.setCreateTime(transDateFormat(answerList.get(i).getAnswerTime()));
                    answers.add(answer);
                }
                PlanChapterAnnotationVO.Answer createAnswer = new PlanChapterAnnotationVO.Answer();
                createAnswer.setCreator(getUserNameByLoginCode(annotationEntity.getCreatorCode()));
                createAnswer.setAction("创建");
                createAnswer.setCreateTime(transDateFormat(annotationEntity.getCreateTime()));
                answers.add(createAnswer);


                //仅批注创建人及审批提交人有回复权限
                String curUserLoginCode = SysUtil.getCurrentUserInfo().getLoginCode();
                annotation.setAnswerAuth(curUserLoginCode.equals(annotationEntity.getCreatorCode())
                        || curUserLoginCode.equals(archReview.getCreatorCode()));
                annotation.setAnswers(answers);
                annotations.add(annotation);
            }
        }
        // 重新控制分页
        Page<PlanChapterAnnotationVO> page = new Page<>();
        page.setPageNum(annotationPage.getPageNum());
        page.setPageSize(annotationPage.getPageSize());
        page.setTotalPages(annotationPage.getTotalPages());
        page.setTotalRows(annotationPage.getTotalRows());
        page.setData(annotations);
        return page;
    }

    private String transDateFormat(Long date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        try {
            return format.format(timeFormatter.parse(date.toString()));
        } catch (ParseException e) {
            log.error("时间转换异常:{}", e.getMessage());
            return null;
        }
    }

    @Override
    public boolean closeCirculate(Long circulateId) {
        if (gtDataImitate) {
            return true;
        }
        boolean result = false;
        try {
            GTFinishPendingJobInfo finishPendingJobInfo = new GTFinishPendingJobInfo();
            finishPendingJobInfo.setNotifyId(circulateId.toString());
            log.info("关闭门户待办:{}", JSON.toJSONString(finishPendingJobInfo));
            result = gtJobSvc.finishPendingJob(finishPendingJobInfo);
            log.info("关闭门户待办结果:{}", result);
        } catch (Exception e) {
            log.info("关闭门户待办失败:{}", JSON.toJSONString(e));
        }
        return result;
    }
}
